using System;
using System.Windows;


namespace Expression.Samples.Physics {
	public struct Vector {
		internal double _x;
		internal double _y;

		public Vector(double x, double y) {
			this._x = x;
			this._y = y;
		}

		public static bool operator ==(Vector v1, Vector v2) {
			if ((v1.X == v2.X) && (v1.Y == v2.Y))
				return true;
			return false;
		}

		public static bool operator !=(Vector v1, Vector v2) {
			return !(v1 == v2);
		}

		public double X {
			get { return this._x; }
			set { this._x = value; }
		}

		public double Y {
			get { return this._y; }
			set { this._y = value; }
		}

		public override bool Equals(object o) {
			if ((o == null) || !(o is Vector))
				return false;

			Vector vector = (Vector)o;
			return Equals(this, vector);
		}

		public static bool Equals(Vector vector1, Vector vector2) {
			if (vector1.X.Equals(vector2.X)) {
				return vector1.Y.Equals(vector2.Y);
			}
			return false;
		}

		public override int GetHashCode() {
			return (this.X.GetHashCode() ^ this.Y.GetHashCode());
		}

		public double LengthSquared {
			get { return ((this.X * this.X) + (this.Y * this.Y)); }
		}

		public void Normalize() {
			this = (Vector)(this / Math.Max(Math.Abs(this.X), Math.Abs(this.Y)));
			this = (Vector)(this / this.Length);
		}

		public static Vector operator *(double scalar, Vector vector) {
			return new Vector(vector._x * scalar, vector._y * scalar);
		}

		public static Vector operator *(Vector vector, double scalar) {
			return new Vector(vector._x * scalar, vector._y * scalar);
		}

		public static Vector operator /(Vector vector, double scalar) {
			return (Vector)(vector * (1 / scalar));
		}

		public double Length {
			get {
				return Math.Sqrt((this._x * this._x) + (this._y * this._y));
			}
		}

		public static Vector operator +(Vector vector1, Vector vector2) {
			return new Vector(vector1._x + vector2._x, vector1._y + vector2._y);
		}

		public static Vector operator -(Vector vector1, Vector vector2) {
			return new Vector(vector1._x - vector2._x, vector1._y - vector2._y);
		}

		public static Vector operator -(Vector vector) {
			return new Vector(-vector._x, -vector._y);
		}

		public static double operator *(Vector vector1, Vector vector2) {
			return ((vector1._x * vector2._x) + (vector1._y * vector2._y));
		}

		public override string ToString() {
			return this.X + "," + this.Y;
		}

		public static implicit operator Point(Vector vector) {
			return new Point(vector.X, vector.Y);
		}

		public static implicit operator Vector(Box2DX.Common.Vector2 vector) {
			return new Vector(vector.X, vector.Y);
		}

		public static implicit operator Box2DX.Common.Vector2(Vector vector) {
			return new Box2DX.Common.Vector2((float)vector.X, (float)vector.Y);
		}
	}
}
